package com.camel.base.controller;

import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.camel.base.config.ExceptionMsgConstants;
import com.camel.core.enums.YesNo;
import com.camel.base.feign.SysUserService;
import com.camel.base.model.*;
import com.camel.base.model.tem.AnswerSubmit;
import com.camel.base.service.*;
import com.camel.base.utils.StringFormatUtil;
import com.camel.core.controller.BaseCommonController;
import com.camel.core.entity.Result;
import com.camel.core.enums.EntityStatus;
import com.camel.core.exceptions.CustomException;
import com.camel.core.model.SysUser;
import com.camel.core.service.BaseCommonService;
import com.camel.core.utils.ResultUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.io.Serializable;
import java.util.*;

/**
 * @author camel
 */
@RestController
@RequestMapping("zsAnswer")
public class ZsAnswerController extends BaseCommonController<ZsAnswer> {

    @Autowired
    private ZsAnswerService<ZsAnswer> service;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private ZsSeatService<ZsSeat> seatService;

    @Autowired
    private ZsAnswerItemService<ZsAnswerItem> zsAnswerItemService;

    @Autowired
    private ZsOptionService<ZsOption> optionService;

    @Autowired
    private ZsInformationService<ZsInformation> informationService;

    @Autowired
    private ZsSurveyService<ZsSurvey> surveyService;

    /**
     * 根据问题列表中的答案信息保存
     *
     * @param submit
     * @return
     */
    @Transactional
    @PostMapping("/submit/{phone}/{uuid}")
    public Result answer(@RequestBody AnswerSubmit submit, @PathVariable String phone, @PathVariable String uuid) {
        List<ZsQuestion> questions = submit.getQuestions();
        Assert.notEmpty(questions, ExceptionMsgConstants.ANSWERS_NOT_NULL);
        Assert.isTrue(!StringUtils.isEmpty(phone), ExceptionMsgConstants.PHONE_ERROR);
        Assert.isTrue(!StringUtils.isEmpty(uuid), ExceptionMsgConstants.CTI_CONFIG_ERROR);
        // 问卷信息
        ZsSurvey survey = surveyService.getById(submit.getSurveyId());
        Assert.notNull(survey, ExceptionMsgConstants.SURVEY_NOT_EXSIT);
        // 问卷是否满额
        if(surveyService.isFull(survey)) {
            throw new CustomException(ExceptionMsgConstants.SURVEY_HAS_BEEN_FULL);
        }
        if(surveyService.isAnsweed(survey.getId(), phone, submit.getLable())) {
            throw new CustomException(ExceptionMsgConstants.PHONE_HAS_BEEN_ANSWERED);
        }

        // 获取当前号码信息
        ZsInformation zsInformation = informationService.selectInfo(submit.getSurveyId(), phone, submit.getLable());
        SysUser currentUser = currentUser();

        // 获取当前坐席
        ZsSeat seat = seatService.getByUid(StpUtil.getLoginIdAsInt());
        Assert.notNull(seat, ExceptionMsgConstants.USER_UNBIND_SEAT);
        // 创建主表对象信息
        ZsAnswer zsAnswer = prepairAnswer(survey.getId(), uuid, phone, seat.getAgentnum(), currentUser, zsInformation);
        // 保存主表
        service.save(zsAnswer);

        List<ZsOption> optionList = new ArrayList<>();
        List<ZsAnswerItem> answerItemList = new ArrayList<>();
        // 逐题保存
        for (ZsQuestion q : questions) {
            // 获取用户选择及回答信息
            List<ZsOption> answerList = q.getAnswers();
            for (ZsOption zsOption : answerList) {
                if(!zsOption.getConfigration().equals(0) && zsOption.getCurrent() >= zsOption.getConfigration()) {
                    throw new CustomException(String.format("第%s题, 所选选项配额已满，若仍能提交，请联系管理员。", q.getOrderNum()) );
                }
                ZsAnswerItem ai = prepairAnswerItem(zsAnswer, q, zsOption, zsInformation);
                zsOption.setCurrent(zsOption.getCurrent() + 1);
                // 选项忽略配额 则不计数
                if(zsOption.getIgnoreNum().equals(YesNo.YES.getValue())) {
                    zsAnswer.setValid(YesNo.NO.getValue());
                }

                answerItemList.add(ai);
                optionList.add(zsOption);
            }
            // 分数累加一下
            zsAnswer.setScore(zsAnswer.getScore() + 0);
        }

        zsAnswerItemService.saveBatch(answerItemList);
        optionService.saveOrUpdateBatch(optionList);
        if (zsAnswer.getScore() > 0) {
            service.updateById(zsAnswer);
        }

        // 刚刚作答的答案 只需校验是否有效即可
        if(zsAnswer.getValid().equals(YesNo.YES.getValue())) {
            survey.setCurrentNum(survey.getCurrentNum() + 1);
            surveyService.updateById(survey);
        }

        return ResultUtil.success("样本提交成功");
    }

    /**
     * 查询答题详情（选项）
     * @param id
     * @return
     */
    @GetMapping("/options/detail")
    public Result details(@RequestParam("id") Serializable id) {
        LambdaQueryWrapper<ZsAnswerItem> eq = new LambdaQueryWrapper<ZsAnswerItem>().eq(ZsAnswerItem::getAnswerId, id);
        List<ZsAnswerItem> list = zsAnswerItemService.list(eq);
        return ResultUtil.success(list);
    }

    /**
     * 审核通过
     * @param entity
     * @return
     */
    @PutMapping("/pass")
    public Result pass(@RequestBody ZsAnswer entity) {
        SysUser currentUser = currentUser();
        if(ObjectUtils.isEmpty(currentUser)) {
            throw new NotLoginException(NotLoginException.NOT_TOKEN_MESSAGE, "", "");
        }

        entity.setValid(YesNo.YES.getValue());
        entity.setReviewStatus(YesNo.YES.getValue());
        entity.setReviewMsg("通过（默认）");
        entity.setReviewer(currentUser.getUserId());
        entity.setReviewerName(currentUser.getUserName());
        if(service.updateById(entity)) {
            return ResultUtil.success();
        }
        return ResultUtil.error("操作失败");
    }

    /**
     * 审核作废
     * @param entity
     * @return
     */
    @PutMapping("/cancel")
    public Result cancel(@RequestBody ZsAnswer entity) {
        SysUser currentUser = currentUser();
        if(ObjectUtils.isEmpty(currentUser)) {
            throw new NotLoginException(NotLoginException.NOT_TOKEN_MESSAGE, "", "");
        }
        entity.setValid(YesNo.NO.getValue());
        entity.setReviewStatus(2);
        entity.setReviewer(currentUser.getUserId());
        entity.setReviewerName(currentUser.getUserName());
        if(service.updateById(entity)) {
            return ResultUtil.success();
        }
        return ResultUtil.error("操作失败");
    }

    @Override
    public boolean deleteAble(Serializable id) {
        ZsAnswer byId = service.getById(id);
        if (ObjectUtils.isEmpty(byId)) {
            throw new CustomException("删除失败: " + getMouduleName() + "不存在");
        }
        return true;
    }

    public SysUser currentUser() {
        Result detail = sysUserService.detail(StpUtil.getLoginIdAsInt());
        if (detail.isSuccess() && !ObjectUtils.isEmpty(detail.getData())) {
            return new ObjectMapper().convertValue(detail.getData(), SysUser.class);
        } else {
            throw new CustomException("当前登录人信息不正确！ 请联系管理员");
        }
    }

    /**
     * 准备样本数据
     * @return
     */
    public ZsAnswer prepairAnswer(Integer surveyId, String agentUuid, String phone, String agentNum, SysUser currentUser, ZsInformation information) {
        ZsAnswer zsAnswer = new ZsAnswer();
        zsAnswer.setSurveyId(surveyId);
        zsAnswer.setAgentUuid(agentUuid);
        zsAnswer.setPhone(phone);
        zsAnswer.setSeat(agentNum);
        zsAnswer.setUid(currentUser.getUserId());
        zsAnswer.setWorkNum(currentUser.getWorkNum());
        zsAnswer.setUsername(currentUser.getUserName());
        if(!ObjectUtils.isEmpty(information)) {
            zsAnswer.setLabel(information.getLable());
        }

        // 预设分值0
        zsAnswer.setScore(0.0);
        zsAnswer.setUpdateAt(new Date());
        zsAnswer.setCreator(StpUtil.getLoginIdAsInt());
        zsAnswer.setCreateAt(new Date());
        zsAnswer.setStatus(EntityStatus.NORMAL);
        zsAnswer.setValid(YesNo.YES.getValue());
        return zsAnswer;
    }

    /**
     * 准备样本数据
     * @return
     */
    public ZsAnswerItem prepairAnswerItem(ZsAnswer answer, ZsQuestion q, ZsOption zsOption, ZsInformation zsInformation) {
        ZsAnswerItem ai = new ZsAnswerItem();
        ai.setAnswerId(answer.getId());
        ai.setSurveyId(answer.getSurveyId());
        ai.setQuestionId(q.getId());
        if (!ObjectUtils.isEmpty(zsOption.getScore())) {
            ai.setScore(zsOption.getScore());
        } else {
            ai.setScore(0.0);
        }
        ai.setOptionId(zsOption.getId());
        ai.setOptionName(zsOption.getName());
        ai.setQuestionId(zsOption.getQuestionId());
        ai.setType(zsOption.getOtype());
        ai.setCreator(StpUtil.getLoginIdAsInt());
        ai.setCreateAt(new Date());
        ai.setUpdator(StpUtil.getLoginIdAsInt());
        ai.setUpdateAt(new Date());
        ai.setRemark(zsOption.getRemark());
        // 如果用户手写过，则用手写备注
        String s = StringUtils.isEmpty(zsOption.getRemark()) ? zsOption.getName() : zsOption.getRemark();
        // 如果用户信息不为空则适当的填充
        if(!ObjectUtils.isEmpty(zsInformation) && !StringUtils.isEmpty(zsInformation.getInfomation())) {
            ai.setValue(StringFormatUtil.stringFormat(s, JSONObject.parseObject(zsInformation.getInfomation())));
        } else {
            ai.setValue(zsOption.getName());
        }
        return ai;
    }

    @Override
    public BaseCommonService<ZsAnswer> getiService() {
        return service;
    }

    @Override
    public String getMouduleName() {
        return "样本";
    }
}
